How to change the frequency of GlitchPass?

Hi guys, using the GlitchPass is possible someway to manipulate the frequency of the glitch?
I would like to reduce the frequency so it happens less often and also in a random way (not fixed interval).
Any idea?

2 Likes

The property curF controls how often the glitch occurs. The idea is to change the way how the variable is incremented. Right now, this happens when the pass is going to be rendered:

The idea is to remove this line an update curF in the above if statements. The first and second branches perform the actual glitch, the third branch represents the stationary phase. So incremented curF in the first and second if statement by one. In the third statement incremented it by a smaller value. The lower the value, the longer the phase where nothing happens.

Demo: Fixed Old Glitch Pass - JSFiddle - Code Playground

4 Likes

Thank you! Perfect

This is what worked for me.
Change the 0.1 in if (Math.random() < 0.1) { to a higher value for a more frequent glitch.

import {
    DataTexture,
    FloatType,
    MathUtils,
    RGBFormat,
    ShaderMaterial,
    UniformsUtils
} from "three";
import { Pass } from "three/examples/jsm/postprocessing/Pass"
import { DigitalGlitch } from "three/examples/jsm/shaders/DigitalGlitch"

var GlitchPass = function ( dt_size ) {

    Pass.call( this );

    if ( DigitalGlitch === undefined ) console.error( "GlitchPass relies on DigitalGlitch" );

    var shader = DigitalGlitch;
    this.uniforms = UniformsUtils.clone( shader.uniforms );

    if ( dt_size == undefined ) dt_size = 64;


    this.uniforms[ "tDisp" ].value = this.generateHeightmap( dt_size );


    this.material = new ShaderMaterial( {
        uniforms: this.uniforms,
        vertexShader: shader.vertexShader,
        fragmentShader: shader.fragmentShader
    } );

    this.fsQuad = new Pass.FullScreenQuad( this.material );

    this.goWild = false;
    this.curF = 1;
    this.generateTrigger();

};

GlitchPass.prototype = Object.assign( Object.create( Pass.prototype ), {

    constructor: GlitchPass,

    render: function ( renderer, writeBuffer, readBuffer /*, deltaTime, maskActive */ ) {

        this.uniforms[ "tDiffuse" ].value = readBuffer.texture;
        this.uniforms[ 'seed' ].value = Math.random();//default seeding
        this.uniforms[ 'byp' ].value = 0;

        if ( this.curF % this.randX == 0 || this.goWild == true ) {
            this.uniforms[ 'amount' ].value = Math.random() / 30;
            this.uniforms[ 'angle' ].value = MathUtils.randFloat( - Math.PI, Math.PI );
            this.uniforms[ 'seed_x' ].value = MathUtils.randFloat( - 1, 1 );
            this.uniforms[ 'seed_y' ].value = MathUtils.randFloat( - 1, 1 );
            this.uniforms[ 'distortion_x' ].value = MathUtils.randFloat( 0, 1 );
            this.uniforms[ 'distortion_y' ].value = MathUtils.randFloat( 0, 1 );
            this.curF = 0;
            this.generateTrigger();

        } else if ( this.curF % this.randX < this.randX / 5 ) {
            this.uniforms[ 'amount' ].value = Math.random() / 90;
            this.uniforms[ 'angle' ].value = MathUtils.randFloat( - Math.PI, Math.PI );
            this.uniforms[ 'distortion_x' ].value = MathUtils.randFloat( 0, 1 );
            this.uniforms[ 'distortion_y' ].value = MathUtils.randFloat( 0, 1 );
            this.uniforms[ 'seed_x' ].value = MathUtils.randFloat( - 0.3, 0.3 );
            this.uniforms[ 'seed_y' ].value = MathUtils.randFloat( - 0.3, 0.3 );
            this.curF ++;

        } else if ( this.goWild == false ) {
            if (Math.random() < 0.1) {
                this.curF ++;
            }
            this.uniforms[ 'byp' ].value = 1;
        }

        if (this.curF % this.randX == 0 || this.goWild == true) {
            this.curF ++;
        }

        if ( this.renderToScreen ) {

            renderer.setRenderTarget( null );
            this.fsQuad.render( renderer );

        } else {

            renderer.setRenderTarget( writeBuffer );
            if ( this.clear ) renderer.clear();
            this.fsQuad.render( renderer );

        }

    },

    generateTrigger: function () {

        this.randX = MathUtils.randInt( 120, 240 );

    },

    generateHeightmap: function ( dt_size ) {

        var data_arr = new Float32Array( dt_size * dt_size * 3 );
        var length = dt_size * dt_size;

        for ( var i = 0; i < length; i ++ ) {

            var val = MathUtils.randFloat( 0, 1 );
            data_arr[ i * 3 + 0 ] = val;
            data_arr[ i * 3 + 1 ] = val;
            data_arr[ i * 3 + 2 ] = val;

        }

        return new DataTexture( data_arr, dt_size, dt_size, RGBFormat, FloatType );

    }

} );

export { GlitchPass };

I have the same problem, but for some reason both solutions don’t work for me.

I reverted to @Mugen87 's solution (see below, maybe I did a mistake? the jsfiddle doesn’t work anymore)

but even a very low increment value the “normal” glitch still happens every 2-3 seconds.

I’d like to stop the regular, lighter glitches completely, and being able to trigger them just like goWild, only when a certain variable is set to true. does it make sense?
That would be the only way for me to time the glitches precisely, not with a vague random interval.

render( renderer, writeBuffer, readBuffer /*, deltaTime, maskActive */ ) {

  this.uniforms[ 'tDiffuse' ].value = readBuffer.texture;
  this.uniforms[ 'seed' ].value = Math.random();//default seeding
  this.uniforms[ 'byp' ].value = 0;

  if ( this.curF % this.randX == 0 || this.goWild == true ) {

  	this.uniforms[ 'amount' ].value = Math.random() / 30;
  	this.uniforms[ 'angle' ].value = MathUtils.randFloat( - Math.PI, Math.PI );
  	this.uniforms[ 'seed_x' ].value = MathUtils.randFloat( - 1, 1 );
  	this.uniforms[ 'seed_y' ].value = MathUtils.randFloat( - 1, 1 );
  	this.uniforms[ 'distortion_x' ].value = MathUtils.randFloat( 0, 1 );
  	this.uniforms[ 'distortion_y' ].value = MathUtils.randFloat( 0, 1 );
  	this.curF = 0;
  	this.generateTrigger();

  	this.curF ++;

  } else if ( this.curF % this.randX < this.randX / 5 ) {

  	this.uniforms[ 'amount' ].value = Math.random() / 90;
  	this.uniforms[ 'angle' ].value = MathUtils.randFloat( - Math.PI, Math.PI );
  	this.uniforms[ 'distortion_x' ].value = MathUtils.randFloat( 0, 1 );
  	this.uniforms[ 'distortion_y' ].value = MathUtils.randFloat( 0, 1 );
  	this.uniforms[ 'seed_x' ].value = MathUtils.randFloat( - 0.3, 0.3 );
  	this.uniforms[ 'seed_y' ].value = MathUtils.randFloat( - 0.3, 0.3 );

  	this.curF ++;

  } else if ( this.goWild == false ) {

  	this.uniforms[ 'byp' ].value = 1;
  
  	this.curF += 0.0000001; ///////////////////////////////////// glitch frequency

  }



  if ( this.renderToScreen ) {

  	renderer.setRenderTarget( null );
  	this.fsQuad.render( renderer );

  } else {

  	renderer.setRenderTarget( writeBuffer );
  	if ( this.clear ) renderer.clear();
  	this.fsQuad.render( renderer );

  }

}

I fixed the GlitchPass Demo

<script src="https://threejs.org/build/three.js"></script>
<script src="https://threejs.org/examples/js/shaders/CopyShader.js"></script>
<script src="https://threejs.org/examples/js/shaders/DigitalGlitch.js"></script>
<script src="https://threejs.org/examples/js/postprocessing/EffectComposer.js"></script>
<script src="https://threejs.org/examples/js/postprocessing/RenderPass.js"></script>
<script src="https://threejs.org/examples/js/postprocessing/GlitchPass.js"></script> /** needed to add the actual glitchPass script
<script src="https://threejs.org/examples/js/postprocessing/MaskPass.js"></script>
<script src="https://threejs.org/examples/js/postprocessing/ShaderPass.js"></script>
<script>
/**
 * @author alteredq / http://alteredqualia.com/
 */

THREE.GlitchPass = function ( dt_size ) {

	THREE.Pass.call( this );

	if ( THREE.DigitalGlitch === undefined ) console.error( "THREE.GlitchPass relies on THREE.DigitalGlitch" );

	var shader = new THREE.DigitalGlitch;
	this.uniforms = THREE.UniformsUtils.clone( shader.uniforms );

	if ( dt_size == undefined ) dt_size = 64;


	this.uniforms[ "tDisp" ].value = this.generateHeightmap( dt_size );


	this.material = new THREE.ShaderMaterial( {
		uniforms: this.uniforms,
		vertexShader: shader.vertexShader,
		fragmentShader: shader.fragmentShader
	} );

	this.camera = new THREE.OrthographicCamera( - 1, 1, 1, - 1, 0, 1 );
	this.scene = new THREE.Scene();

	this.quad = new THREE.Mesh( new THREE.PlaneBufferGeometry( 2, 2 ), null );
	this.quad.frustumCulled = false; // Avoid getting clipped
	this.scene.add( this.quad );

	this.goWild = false;
	this.curF = 0;
	this.generateTrigger();

};

THREE.GlitchPass.prototype = Object.assign( Object.create( THREE.Pass.prototype ), {

        // this was constructor = constructor: THREE.GlitchPass needed to be the line below
	constructor = new THREE.GlitchPass,

	render: function ( renderer, writeBuffer, readBuffer, deltaTime, maskActive ) {

		this.uniforms[ "tDiffuse" ].value = readBuffer.texture;
		this.uniforms[ 'seed' ].value = Math.random();//default seeding
		this.uniforms[ 'byp' ].value = 0;

		if ( this.curF % this.randX == 0 || this.goWild == true ) {

			this.uniforms[ 'amount' ].value = Math.random() / 30;
			this.uniforms[ 'angle' ].value = THREE.Math.randFloat( - Math.PI, Math.PI );
			this.uniforms[ 'seed_x' ].value = THREE.Math.randFloat( - 1, 1 );
			this.uniforms[ 'seed_y' ].value = THREE.Math.randFloat( - 1, 1 );
			this.uniforms[ 'distortion_x' ].value = THREE.Math.randFloat( 0, 1 );
			this.uniforms[ 'distortion_y' ].value = THREE.Math.randFloat( 0, 1 );
			this.curF = 0;
			this.generateTrigger();
			this.curF ++;

		} else if ( this.curF % this.randX < this.randX / 5 ) {

			this.uniforms[ 'amount' ].value = Math.random() / 90;
			this.uniforms[ 'angle' ].value = THREE.Math.randFloat( - Math.PI, Math.PI );
			this.uniforms[ 'distortion_x' ].value = THREE.Math.randFloat( 0, 1 );
			this.uniforms[ 'distortion_y' ].value = THREE.Math.randFloat( 0, 1 );
			this.uniforms[ 'seed_x' ].value = THREE.Math.randFloat( - 0.3, 0.3 );
			this.uniforms[ 'seed_y' ].value = THREE.Math.randFloat( - 0.3, 0.3 );
			this.curF ++;

		} else if ( this.goWild == false ) {

			this.uniforms[ 'byp' ].value = 1;
			this.curF += 0.1;

		}

		this.quad.material = this.material;

		if ( this.renderToScreen ) {

			renderer.setRenderTarget( null );
			renderer.render( this.scene, this.camera );

		} else {

			renderer.setRenderTarget( writeBuffer );
			if ( this.clear ) renderer.clear();
			renderer.render( this.scene, this.camera );

		}

	},

	generateTrigger: function () {

		this.randX = THREE.Math.randInt( 120, 240 );

	},

	generateHeightmap: function ( dt_size ) {

		var data_arr = new Float32Array( dt_size * dt_size * 3 );
		var length = dt_size * dt_size;

		for ( var i = 0; i < length; i ++ ) {

			var val = THREE.Math.randFloat( 0, 1 );
			data_arr[ i * 3 + 0 ] = val;
			data_arr[ i * 3 + 1 ] = val;
			data_arr[ i * 3 + 2 ] = val;

		}

		var texture = new THREE.DataTexture( data_arr, dt_size, dt_size, THREE.RGBFormat, THREE.FloatType );
		texture.needsUpdate = true;
		return texture;

	}

} );

</script>
1 Like